home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / tools / cpx_acc / cpxbasic / sources / basic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  66.2 KB  |  3,002 lines

  1. /* Output from p2c, the Pascal-to-C translator      */
  2. /* From input file "dist/examples/basic.p"          */
  3. /* strongly optimized and extended by O.T,T.D,J.S */
  4.  
  5. #include <time.h>
  6. #include <stdlib.h>
  7. #include <tos.h>
  8. #include "p2c.h"
  9. #include "glo.h"
  10. #include "tokstr.h"
  11.  
  12. Local char filename[255];
  13. Local long fileposition;
  14. Local boolean binary;
  15. Local int useprec;
  16. Local int useprec_;
  17. Local int usewidth;
  18. Local int usewidth_;
  19. Local int useleft;
  20. Local int useleft_;
  21. Local char *adress;
  22. Local long wert;
  23. Local int bytes;
  24. Local boolean tron;
  25.  
  26. extern char *cpx_buffer;
  27.  
  28. #define checking        true
  29. #define varnamelen      20
  30. #define maxdims         4
  31.  
  32. typedef Char varnamestring[varnamelen + 1];
  33. typedef Char string255[256];
  34.  
  35. typedef double numarray[];
  36. typedef Char *strarray[];
  37.  
  38. enum {forloop,whileloop,gosubloop};
  39. enum {CHDIR,MKDIR,RMDIR};
  40.  
  41. typedef struct tokenrec {
  42.     struct tokenrec *next;
  43.     short kind;
  44.     union {
  45.         struct varrec *vp;
  46.         double num;
  47.         Char *sp;
  48.         Char snch;
  49.     } UU;
  50. } tokenrec;
  51.  
  52. typedef struct linerec {
  53.     long num, num2;
  54.     tokenrec *txt;
  55.     struct linerec *next;
  56. } linerec;
  57.  
  58. typedef struct varrec {
  59.     varnamestring name;
  60.     struct varrec *next;
  61.     long dims[maxdims];
  62.     char numdims;
  63.     boolean stringvar;
  64.     union {
  65.         struct {
  66.             double *arr;
  67.             double *val, rv;
  68.         } U0;
  69.         struct {
  70.             Char **sarr;
  71.             Char **sval, *sv;
  72.         } U1;
  73.     } UU;
  74. } varrec;
  75.  
  76. typedef struct valrec {
  77.     boolean stringval;
  78.     union {
  79.         double val;
  80.         Char *sval;
  81.     } UU;
  82. } valrec;
  83.  
  84. typedef struct looprec {
  85.     struct looprec *next;
  86.     linerec *homeline;
  87.     tokenrec *hometok;
  88.     short kind;
  89.     union {
  90.         struct {
  91.             varrec *vp;
  92.             double max, step;
  93.         } U0;
  94.     } UU;
  95. } looprec;
  96.  
  97. typedef struct contsave 
  98. {
  99.     linerec *saveline;
  100.     tokenrec *savetok;
  101.     boolean savegoto,saveelse,flagcont;
  102.     int cm;
  103.     char rev_mode;
  104. } contsave;
  105.  
  106. Static contsave contvar;
  107.     
  108. Static Char inbuf[256];
  109.  
  110. Static linerec *linebase;
  111. Static varrec *varbase;
  112. Static looprec *loopbase;
  113.  
  114. Static long curline;
  115. Static linerec *stmtline, *dataline;
  116. Static tokenrec *stmttok, *datatok, *buf;
  117.  
  118. Static boolean exitflag;
  119.  
  120. extern long EXCP_LINE;
  121. extern int esc,cx,cy,cm,chc;
  122. extern char rev_mode,rev_off;
  123.  
  124. #include "proto.h"
  125.  
  126. Static Void disposetokens( tokenrec **tok );
  127.  
  128. /* Feststellen, ob Buchstabe ein Variablenbezeichner sein kann */
  129. int isvar(int a)
  130. {
  131.     return a=='$'||a=='_'||a=='.'||isalnum(a);
  132. }
  133.  
  134. int isvarstr(int a)
  135. {
  136.     return a=='"'||a=='\''||isvar(a);
  137. }
  138.  
  139. Local int unit;
  140.  
  141. /* unit in radiant umrechnen */
  142. Local double to_rad(double x)
  143. {
  144.     switch(unit)
  145.     {
  146.         case tokdegree:
  147.             x*=M_PI/180.;
  148.             break;
  149.         case tokgrad:
  150.             x*=M_PI/200.;
  151.             break;
  152.     }
  153.     return x;
  154. }
  155.  
  156. /* Radiant in unit umrechnen */
  157. Local double from_rad(double x)
  158. {
  159.     switch(unit)
  160.     {
  161.         case tokdegree:
  162.             x*=180./M_PI;
  163.             break;
  164.         case tokgrad:
  165.             x*=200./M_PI;
  166.             break;
  167.     }
  168.     return x;
  169. }
  170.  
  171. /* Dezimalgrad in Grad,Min,Sec umrechnen */
  172. Local char *dms(char *s,double x)
  173. {
  174.     char *p;
  175.     long h;
  176.     int min,sec;
  177.     h=(long)x;
  178.     x-=h;
  179.     if(x<0) x=-x;
  180.     x*=60.;
  181.     min=(int)x;
  182.     x-=min;
  183.     x*=60.;
  184.     sec=(int)x;
  185.     x-=sec;
  186.     x*=1000;
  187.     sprintf(s,"%ld:%02d:%02d,%01d",h,min,sec,(int)x);
  188.     p=s;
  189.     while(p[1]) p++;
  190.     while(*p=='0') p--;
  191.     if(*p==',') p--;
  192.     p[1]=0;
  193.     return s;
  194. }
  195.  
  196. /* String der Form HH:MM:SS,msec in Dezimalgrad umrechnen */
  197. Local double deg(char *s)
  198. {
  199.     double erg=0,fac=1.;
  200.     int i=3,vorz=0;
  201.     char *p,save;
  202.     if(*s=='-')
  203.     {
  204.         vorz=1;
  205.         s++;
  206.     }
  207.     if(*s=='+') s++;
  208.     while(*s&&i-->0)
  209.     {
  210.         p=s;
  211.         while(*s&&isdigit(*s)) s++;
  212.         save=*s;
  213.         *s=0;
  214.         erg+=atol(p)*fac;
  215.         fac*=+(1./60.);
  216.         if((*s=save)!=0) s++;
  217.     }
  218.     if(*s)
  219.     {
  220.         fac=+(1./36000.);
  221.         while(*s&&isdigit(*s))
  222.         {
  223.             erg+=(*s++-'0')*fac;
  224.             fac*=.1;
  225.         }
  226.     }
  227.     return vorz?-erg:erg;
  228. }
  229.  
  230. Local void set_path(int what)
  231. {
  232.     int drvbit;
  233.     static char buffer[200];
  234.     static int olddrv;
  235.  
  236.     if(what)
  237.     {
  238.         olddrv=Dgetdrv();
  239.         Dgetpath(buffer,0);
  240.         drvbit=(int)Dsetdrv(cpx_buffer[0]);
  241.         if((drvbit&(1<<cpx_buffer[0]))==0) Dsetdrv(0);
  242.         Dsetpath(cpx_buffer+1);
  243.     }
  244.     else
  245.     {
  246.         Dsetdrv(olddrv);
  247.         Dsetpath(buffer);
  248.     }
  249. }
  250.  
  251. Static Void restoredata( Void )
  252. {
  253.     dataline = NULL;
  254.     datatok = NULL;
  255. }
  256.  
  257. Static Void clearloops( Void )
  258. {
  259.     looprec *l;
  260.     contsave *cont=&contvar;
  261.  
  262.     disposetokens(&(cont->savetok));
  263.     cont->flagcont=false;
  264.     while (loopbase != NULL)
  265.     {
  266.         l = loopbase->next;
  267.         Free(loopbase);
  268.         loopbase = l;
  269.     }
  270. }
  271.  
  272. Static Void clearvar( varrec *v )
  273. {
  274.     if (v->numdims != 0)
  275.         Free(v->UU.U0.arr);
  276.     else if (v->stringvar && v->UU.U1.sv != NULL)
  277.         Free(v->UU.U1.sv);
  278.     v->numdims = 0;
  279.     if (v->stringvar)
  280.     {
  281.         v->UU.U1.sv = NULL;
  282.         v->UU.U1.sval = &v->UU.U1.sv;
  283.     }
  284.     else
  285.     {
  286.         v->UU.U0.rv = 0.0;
  287.         v->UU.U0.val = &v->UU.U0.rv;
  288.     }
  289. }
  290.  
  291. Static Void clearvars( Void )
  292. {
  293.     varrec *v;
  294.  
  295.     v = varbase;
  296.     while (v != NULL)
  297.     {
  298.         clearvar(v);
  299.         v = v->next;
  300.     }
  301. }
  302.  
  303. Static Char *numtostr( Char *Result, double n )
  304. {
  305.     char *s,*p;
  306.     double x=fabs(n);
  307.     if (n == 0 || ( x>=pow(10,-useprec) && x>=1e-4 && x<1e7 ))
  308.         sprintf(Result, "%#.*lf",useprec,n);
  309.     else
  310.     {
  311.         sprintf(Result, "%#.*lE",useprec,n);
  312.         s=Result;
  313.         while(*s&&*s++!='E');
  314.         while(*s&&*s!='0') s++;
  315.         p=s;
  316.         while(*s&&*s=='0') s++;
  317.         while((*p++=*s++)!=0);
  318.     }
  319.     s=Result;
  320.     while(*s!=0&&*s!='E') s++;
  321.     p=s--;
  322.     while(*s=='0') *s--=' ';
  323.     if(*s=='.') *s--=' ';
  324.     s++;
  325.     while(*p!=0) *s++=*p++;
  326.     while(*s!=0) *s++=' ';
  327.     if(usewidth==0)
  328.     {
  329.         s=Result;
  330.         while(*s&&*s!=' ') s++;
  331.         *s=0;
  332.     }
  333.     return Result;
  334. }
  335.  
  336. #define toklength  20
  337. typedef long chset[9];
  338.  
  339. /*
  340. ** compare strings 
  341. ** läßt bei all=true Abkürzungen zu
  342. ** bei all=false wird nur auf Länge von cmp verglichen
  343. */
  344.  
  345. int Sstrcmp(char *inp,char *cmp,int all)
  346. {
  347.     while(1)
  348.     {
  349.         if(all&&*inp=='.')
  350.         {
  351.             inp++;
  352.             while(*cmp!=0 && *inp!=*cmp) cmp++;
  353.         }
  354.         if(*inp!=*cmp) return all?1:*cmp;
  355.         if(*inp==0) return 0;
  356.         inp++;
  357.         cmp++;
  358.     }
  359. }
  360.  
  361. /*
  362. **    modus:    ==0 nichtalphanumersische Zeichen
  363. **            !=0 alphanumerische Zeichen
  364. */
  365. int find_token(char *token,int num,int modus)
  366. {
  367.     char **tok_ptr,*ptr=token;
  368.     char buf[256];
  369.     if(modus!=0) ptr=strupr(strcpy(buf,token));
  370.     tok_ptr=tok_strings+num;
  371.     while(Sstrcmp(ptr,*tok_ptr--,modus) && --num>=0);
  372.     return num;
  373. }
  374.  
  375. /*
  376. ** Wandele einen Ascii in eine Zahl um
  377. ** wenn diese außerhalb des Wertebereiches liegt, Ergebnis<0
  378. */
  379.  
  380. static int getnum(int base,int ch)
  381. {
  382.     if(ch>='a')         ch-='a'-10;
  383.     else if(ch>='A') ch-='A'-10;
  384.     else if(ch<='9') ch-='0';
  385.     if(ch>=base) ch=-1;
  386.     return ch;
  387. }
  388.  
  389. Static Void parse( Char *inbuf, tokenrec **buf )
  390. {
  391.     int j;
  392.     Char token[toklength + 1];
  393.     tokenrec *t, *tptr;
  394.     varrec *v;
  395.     int ch,i;
  396.     double  d,d1,n,rcpbase;
  397.     char *s;
  398.  
  399.     tptr = NULL;
  400.     *buf = NULL;
  401.     do
  402.     {
  403.         while (*inbuf && *inbuf == ' '|| *inbuf=='\t') inbuf++;
  404.         if(*inbuf)
  405.         {
  406.             ch=*inbuf;
  407.             t = (tokenrec *)BASalloc(sizeof(tokenrec));
  408.             if (tptr == NULL)
  409.                 *buf = t;
  410.             else
  411.                 tptr->next = t;
  412.             tptr = t;
  413.                t->next = NULL;
  414.             t->kind=-1;
  415.                if(ch=='"'||ch=='\'')
  416.                {
  417.                 t->kind = tokstr;
  418.                 s=t->UU.sp = (Char *)BASalloc(256);
  419.                 j = 0;
  420.                 inbuf++;
  421.                 while (*inbuf && *inbuf != ch)
  422.                 {
  423.                     *s++ = *inbuf++;
  424.                 }
  425.                 inbuf++;
  426.             }
  427.             else
  428.             {
  429.                 t->kind=j=find_token(inbuf,TOK_ALPHA-1,0);
  430.                 if(j>=0)
  431.                 {
  432.                     inbuf+=strlen(tok_strings[j]);
  433.                 }
  434.                 else
  435.                 {
  436.                     inbuf++;
  437.                     if(isalpha(ch))
  438.                     {
  439.                         inbuf--;
  440.                         j = 0;
  441.                         token[toklength] = '\0';
  442.                         while(*inbuf &&isvar(*inbuf))
  443.                         {
  444.                             if(j<toklength) token[j++] = *inbuf;
  445.                             inbuf++;
  446.                         }
  447.                         token[j] = '\0';
  448.                         t->kind=j=find_token(token,NUM_TOKS-1,1);
  449.                         if (j==tokrem)
  450.                         {
  451.                             t->UU.sp = (Char *)BASalloc(256);
  452.                             sprintf(t->UU.sp, "%s", inbuf);
  453.                             while(*inbuf) inbuf++;
  454.                         }
  455.                         if(j<0)
  456.                         {
  457.                             t->kind = tokvar;
  458.                             v = varbase;
  459.                             while (v != NULL && strcmp(v->name, token))
  460.                                 v = v->next;
  461.                             if (v == NULL) {
  462.                                 v = (varrec *)BASalloc(sizeof(varrec));
  463.                                 v->next = varbase;
  464.                                 varbase = v;
  465.                                 strcpy(v->name, token);
  466.                                 v->numdims = 0;
  467.                                 if (token[strlen(token) - 1] == '$') {
  468.                                     v->stringvar = true;
  469.                                     v->UU.U1.sv = NULL;
  470.                                     v->UU.U1.sval = &v->UU.U1.sv;
  471.                                 } else {
  472.                                     v->stringvar = false;
  473.                                     v->UU.U0.rv = 0.0;
  474.                                     v->UU.U0.val = &v->UU.U0.rv;
  475.                                 }
  476.                             }
  477.                             t->UU.vp = v;
  478.                         }
  479.                     }
  480.                     else if(isdigit(ch)||ch == '.'||ch == '$'||
  481.                                     ch =='%'||ch=='&')
  482.                     {
  483.                         int base=10;
  484.                         t->kind = tokdec;
  485.                         switch(ch)
  486.                         {
  487.                             case '$':
  488.                                 base=16;
  489.                                 t->kind = tokhex;
  490.                                 break;
  491.                             case '&':
  492.                                 base=8;
  493.                                 t->kind = tokoct;
  494.                                    break;
  495.                             case '%':
  496.                                 base=2;
  497.                                 t->kind = tokbin;
  498.                         }
  499.                         if(base==10) inbuf--;
  500.                         rcpbase=1./base;
  501.                         d=0;
  502.                         while(*inbuf)
  503.                         {
  504.                             if((ch=getnum(base,*inbuf))<0) break;
  505.                             d=d*base+ch;
  506.                             inbuf++;
  507.                         }
  508.                         if(*inbuf=='.')
  509.                         {
  510.                             inbuf++;
  511.                             d1=0;
  512.                             n=rcpbase;
  513.                             while(*inbuf)
  514.                             {
  515.                                 if((ch=getnum(base,*inbuf))<0) break;
  516.                                 d1=d1+ch*n;
  517.                                 n*=rcpbase;
  518.                                 inbuf++;
  519.                             }
  520.                             d+=d1;
  521.                         }
  522.                         if(*inbuf=='e'||*inbuf=='E'||*inbuf=='@')
  523.                         {
  524.                             inbuf++;
  525.                             n=base;
  526.                             if(*inbuf=='-'||*inbuf=='+')
  527.                             {
  528.                                 if(*inbuf++=='-') n=rcpbase;
  529.                             }
  530.                             i=0;
  531.                             while(*inbuf)
  532.                             {
  533.                                 if((ch=getnum(base,*inbuf))<0)break;
  534.                                 i=i*base+ch;
  535.                                 inbuf++;
  536.                             }
  537.                             while(i-->0) d*=n;
  538.                         }
  539.                         t->UU.num = d;
  540.                     }
  541.                     else
  542.                     {
  543.                         t->kind = toksnerr;
  544.                         t->UU.snch = ch;
  545.                     }
  546.                 }
  547.             }
  548.             switch(t->kind)
  549.             {
  550.                 case tokatan:
  551.                     t->kind=tokarctan;break;
  552.                 case toklog:
  553.                     t->kind=tokln;break;
  554.                 case toksqr:
  555.                     t->kind=toksqu;break;
  556.                 case toklps:
  557.                     t->kind=toklp;break;
  558.                 case tokrps:
  559.                     t->kind=tokrp;break;
  560.                 case tokprints:
  561.                     t->kind=tokprint;break;
  562.                 case tokinputs:
  563.                     t->kind=tokinput;break;
  564.                 case tokcd:
  565.                     t->kind=tokchdir;break;
  566.             }
  567.         }
  568.     }
  569.     while (*inbuf);
  570.     BreakBASIC();
  571. }
  572.  
  573. #undef toklength
  574.  
  575. static int ins;
  576.  
  577. Static Void listtokens( FILE *f, tokenrec *buf )
  578. {
  579.     int tok;
  580.     Char STR1[256],*s;
  581.     int lastchar=0,oldprec=useprec;
  582.     
  583.     useprec=10;
  584.     while (buf != NULL)
  585.     {
  586.         tok=buf->kind;
  587.         if(tok==tokfor||tok==tokwhile) ins+=2;
  588.         if(tok==toknext||tok==tokwend)
  589.         {
  590.             if((ins-=2)<=0) ins=2;
  591.         }
  592.         switch (tok)
  593.         {
  594.         case tokvar:
  595.             strcpy(STR1,buf->UU.vp->name);
  596.             break;
  597.         case tokdec:
  598.             numtostr(STR1, buf->UU.num);
  599.             s=STR1;
  600.             while(*s!=' ') s++;
  601.             *s=0;
  602.             break;
  603.         case tokoct:
  604.             sprintf(STR1,"&%lo",(long)buf->UU.num);
  605.             break;
  606.         case tokhex:
  607.             sprintf(STR1,"$%lX",(long)buf->UU.num);
  608.             break;
  609.         case tokbin:
  610.             *STR1='%';
  611.             ltoa((long)buf->UU.num,STR1+1,2);
  612.             break;
  613.         case tokstr:
  614.             tok='\'';
  615.             s=buf->UU.sp;
  616.             if(strchr(s,'\'')!=NULL) tok='"';
  617.             sprintf(STR1, "%c%s%c",tok,s,tok);
  618.             break;
  619.         case toksnerr:
  620.             sprintf(STR1, "{%c}", buf->UU.snch);
  621.             break;
  622.         case tokrem:
  623.             sprintf(STR1, "REM%s", buf->UU.sp);
  624.             break;
  625.         default:
  626.             strcpy(STR1,tok_strings[tok]);
  627.         }
  628.         buf = buf->next;
  629.         s=STR1;
  630.         if(isvarstr(*s)&&isvarstr(lastchar)) PUTC(' ',f);
  631.         while(*s++);
  632.         lastchar=*(s-2);
  633.         FPUTS(STR1,f);
  634.     }
  635.     useprec=oldprec;
  636.     BreakBASIC();
  637. }
  638.  
  639. Static Void disposetokens( tokenrec **tok )
  640. {
  641.     tokenrec *tok1;
  642.  
  643.     while (*tok != NULL)
  644.     {
  645.         tok1 = (*tok)->next;
  646.         if ((*tok)->kind == tokrem || (*tok)->kind == tokstr)
  647.             Free((*tok)->UU.sp);
  648.         Free(*tok);
  649.         *tok = tok1;
  650.     }
  651. }
  652.  
  653. Static Void parseinput( tokenrec **buf )
  654. {
  655.     linerec *l, *l0, *l1;
  656.     Char *s=inbuf;
  657.  
  658.     while(isspace(*s))s++;
  659.     strcpy(inbuf,s);
  660.     curline = 0;
  661.     while (*inbuf != '\0' && isdigit(inbuf[0]))
  662.     {
  663.         curline = curline * 10 + inbuf[0] - '0';
  664.         strcpy(inbuf, inbuf + 1);
  665.     }
  666.     parse(inbuf, buf);
  667.     if (curline == 0) return;
  668.     l = linebase;
  669.     l0 = NULL;
  670.     while (l != NULL && l->num < curline)
  671.     {
  672.         l0 = l;
  673.         l = l->next;
  674.     }
  675.     if (l != NULL && l->num == curline)
  676.     {
  677.         l1 = l;
  678.         l = l->next;
  679.         if (l0 == NULL)
  680.             linebase = l;
  681.         else
  682.             l0->next = l;
  683.         disposetokens(&l1->txt);
  684.         Free(l1);
  685.     }
  686.     if (*buf != NULL)
  687.     {
  688.         l1 = (linerec *)BASalloc(sizeof(linerec));
  689.         l1->next = l;
  690.         if (l0 == NULL)
  691.             linebase = l1;
  692.         else
  693.             l0->next = l1;
  694.         l1->num = curline;
  695.         l1->txt = *buf;
  696.     }
  697.     clearloops();
  698.     restoredata();
  699. }
  700.  
  701. Static Void errormsg( Char *s )
  702. {
  703.     Printf("\007%s", s);
  704.     _Escape(42);
  705. }
  706.  
  707. Static Void snerr( Void )
  708. {
  709.     errormsg("Syntax error");
  710. }
  711.  
  712. Static Void tmerr( Void )
  713. {
  714.     errormsg("Type mismatch error");
  715. }
  716.  
  717. Static Void badsubscr( Void )
  718. {
  719.     errormsg("Bad subscript");
  720. }
  721.  
  722. /* Local variables for exec: */
  723. struct LOC_exec {
  724.     boolean gotoflag, elseflag;
  725.     tokenrec *t;
  726. };
  727.  
  728. Local valrec factor PP((struct LOC_exec *LINK));
  729. Local valrec expr PP((struct LOC_exec *LINK));
  730.  
  731. Local double realfactor( struct LOC_exec *LINK )
  732. {
  733.     valrec n;
  734.  
  735.     n = factor(LINK);
  736.     if (n.stringval)
  737.         tmerr();
  738.     return (n.UU.val);
  739. }
  740.  
  741. Local Char *strfactor( struct LOC_exec *LINK )
  742. {
  743.     valrec n;
  744.  
  745.     n = factor(LINK);
  746.     if (!n.stringval)
  747.         tmerr();
  748.     return (n.UU.sval);
  749. }
  750.  
  751. Local Char *stringfactor( Char *Result, struct LOC_exec *LINK )
  752. {
  753.     valrec n;
  754.  
  755.     n = factor(LINK);
  756.     if (!n.stringval)
  757.         tmerr();
  758.     strcpy(Result, n.UU.sval);
  759.     Free(n.UU.sval);
  760.     return Result;
  761. }
  762.  
  763. Local long intfactor( struct LOC_exec *LINK )
  764. {
  765.     return (long)round(realfactor(LINK));
  766. }
  767.  
  768. Local double realexpr( struct LOC_exec *LINK )
  769. {
  770.     valrec n;
  771.  
  772.     n = expr(LINK);
  773.     if (n.stringval)
  774.         tmerr();
  775.     return (n.UU.val);
  776. }
  777.  
  778. Local Char *strexpr( struct LOC_exec *LINK )
  779. {
  780.     valrec n;
  781.  
  782.     n = expr(LINK);
  783.     if (!n.stringval)
  784.         tmerr();
  785.     return (n.UU.sval);
  786. }
  787.  
  788. Local Char *stringexpr( Char *Result, struct LOC_exec *LINK )
  789. {
  790.     valrec n;
  791.  
  792.     n = expr(LINK);
  793.     if (!n.stringval)
  794.         tmerr();
  795.     strcpy(Result, n.UU.sval);
  796.     Free(n.UU.sval);
  797.     return Result;
  798. }
  799.  
  800. Local long intexpr( struct LOC_exec *LINK )
  801. {
  802.     return (long)round(realexpr(LINK));
  803. }
  804.  
  805. Local Void require( short k, struct LOC_exec *LINK )
  806. {
  807.     int w;
  808.     if (LINK->t == NULL) snerr();
  809.     else
  810.     {
  811.         w=LINK->t->kind;
  812.         if(w>=tokbin&&w<=tokhex) w=tokdec;
  813.         if( w != k)
  814.             snerr();
  815.         LINK->t = LINK->t->next;
  816.     }
  817. }
  818.  
  819. Local Void skipparen( struct LOC_exec *LINK )
  820. {
  821.     do {
  822.         if (LINK->t == NULL)
  823.             snerr();
  824.         if (LINK->t->kind == tokrp || LINK->t->kind == tokcomma)
  825.             goto _L1;
  826.         if (LINK->t->kind == toklp) {
  827.             LINK->t = LINK->t->next;
  828.             skipparen(LINK);
  829.         }
  830.         LINK->t = LINK->t->next;
  831.     } while (true);
  832. _L1:
  833.     ;
  834. }
  835.  
  836. Local varrec *findvar( struct LOC_exec *LINK )
  837. {
  838.     varrec *v;
  839.     long i, j, k;
  840.     tokenrec *tok;
  841.     long FORLIM;
  842.  
  843.     if (LINK->t == NULL || LINK->t->kind != tokvar)
  844.         snerr();
  845.     v = LINK->t->UU.vp;
  846.     LINK->t = LINK->t->next;
  847.     if (LINK->t == NULL || LINK->t->kind != toklp)
  848.     {
  849.         if (v->numdims != 0)
  850.             badsubscr();
  851.         return v;
  852.     }
  853.     if (v->numdims == 0)
  854.     {
  855.         tok = LINK->t;
  856.         i = 0;
  857.         j = 1;
  858.         do
  859.         {
  860.             if (i >= maxdims) badsubscr();
  861.             LINK->t = LINK->t->next;
  862.             skipparen(LINK);
  863.             j *= 11;
  864.             i++;
  865.             v->dims[i - 1] = 11;
  866.         } while (LINK->t->kind != tokrp);
  867.         v->numdims = i;
  868.         if (v->stringvar)
  869.         {
  870.             v->UU.U1.sarr = (Char **)BASalloc(j * sizeof(char*));
  871.             for (k = 0; k < j; k++) v->UU.U1.sarr[k] = NULL;
  872.         }
  873.         else
  874.         {
  875.             v->UU.U0.arr = (double *)BASalloc(j * sizeof(double));
  876.             for (k = 0; k < j; k++) v->UU.U0.arr[k] = 0.0;
  877.         }
  878.         LINK->t = tok;
  879.     }
  880.     k = 0;
  881.     LINK->t = LINK->t->next;
  882.     FORLIM = v->numdims;
  883.     for (i = 1; i <= FORLIM; i++)
  884.     {
  885.         j = intexpr(LINK);
  886.         if ((unsigned long)j >= v->dims[i - 1])
  887.             badsubscr();
  888.         k = k * v->dims[i - 1] + j;
  889.         if (i < v->numdims)
  890.             require(tokcomma, LINK);
  891.     }
  892.     require(tokrp, LINK);
  893.     if (v->stringvar)
  894.         v->UU.U1.sval = &v->UU.U1.sarr[k];
  895.     else
  896.         v->UU.U0.val = &v->UU.U0.arr[k];
  897.     return v;
  898. }
  899.  
  900. long peek(void)
  901. {
  902.     register d=bytes;
  903.     register char *s=adress,*t=(char*)&wert+4-d;
  904.     wert=0;
  905.     peekpoke(s,t,d);
  906.     return wert;
  907. }
  908.  
  909. Local boolean iseos( struct LOC_exec *LINK )
  910. {
  911.     int kind;
  912.     if(LINK->t==NULL) return TRUE;
  913.     kind=LINK->t->kind;
  914.     return (kind == tokelse || kind== tokcolon);
  915. }
  916.  
  917. boolean isseparator( struct LOC_exec *LINK )
  918. {
  919.     return (iseos(LINK) || LINK->t->kind<TOK_ALPHA);
  920. }
  921.     
  922. typedef struct DEVHNDL
  923. {
  924.     int stat;
  925.     int io;
  926. }
  927. DEVHNDL;
  928.  
  929. DEVHNDL *find_dev(char *s)
  930. {
  931.     static DEVHNDL dev;
  932.     static char *dev_str[]=
  933.     {
  934.         "PRN",
  935.         "AUX",
  936.         "CON",
  937.         "MIDI",
  938.         "IKBD",
  939.         "RCON",
  940.         "MOD1",
  941.         "MOD2",
  942.         "SER1",
  943.         "SER2"
  944.     };
  945.     char **t=dev_str+NUM_EL(dev_str)-1;
  946.     int i=(int)NUM_EL(dev_str);
  947.     strupr(s);
  948.     while(--i>=0 && strcmp(s,*t--));
  949.     dev.stat=dev.io=i;
  950.     if(i==3) dev.stat=4;
  951.     else if(i==4) dev.stat=3;
  952.     return &dev;
  953. }
  954.  
  955. Local int cmdoutbyte(struct LOC_exec *LINK,char *TEMPS)
  956. {
  957.     DEVHNDL *dev;
  958.     int erg=-1;
  959.     long TEMPI;
  960.     require(tokcomma,LINK);
  961.     TEMPI=intfactor(LINK);
  962.     dev=find_dev(TEMPS);
  963.     if(dev->io>=0 && Bcostat(dev->stat))
  964.     {
  965.         Bconout(dev->io,(int)TEMPI&0xff);
  966.         erg=0;
  967.     }
  968.     return erg;
  969. }
  970.  
  971. Local int cmdinbyte(char *TEMPS)
  972. {
  973.     int erg=-1;
  974.     DEVHNDL *dev;
  975.     dev=find_dev(TEMPS);
  976.     if(dev->io>=0 && Bconstat(dev->io)) erg=(int)Bconin(dev->io)&0xff;
  977.     return erg;
  978. }
  979.  
  980. Local valrec factor( struct LOC_exec *LINK )
  981. {
  982.     varrec *v;
  983.     tokenrec *facttok;
  984.     valrec n;
  985.     long i, j;
  986.     tokenrec *tok, *tok1;
  987.     static char pfad[140],name[14];
  988.     Char *TEMPS,*t;
  989.     double TEMP;
  990.     long TEMPI;
  991.     int kind,fsel;
  992.     time_t zeit;
  993.  
  994.     if (LINK->t == NULL) snerr();
  995.     facttok = LINK->t;
  996.     LINK->t = LINK->t->next;
  997.     n.stringval = false;
  998.     kind=facttok->kind;
  999.  
  1000.     if(kind==tokmid_)
  1001.     {
  1002.         n.stringval = true;
  1003.         require(toklp, LINK);
  1004.         n.UU.sval=strexpr(LINK);
  1005.         require(tokcomma, LINK);
  1006.         i = intexpr(LINK)-1;
  1007.         if (i<0) i=0;
  1008.         j = 255;
  1009.         if (LINK->t != NULL && LINK->t->kind == tokcomma)
  1010.         {
  1011.             LINK->t = LINK->t->next;
  1012.             j = intexpr(LINK);
  1013.         }
  1014.         TEMPS=n.UU.sval;
  1015.         if (i < strlen(TEMPS))
  1016.         {
  1017.             while(j-->0&&(*TEMPS=TEMPS[i])!=0) TEMPS++;
  1018.         }
  1019.         *TEMPS= '\0';
  1020.         require(tokrp, LINK);
  1021.     }    
  1022.     else
  1023.     {
  1024.         TEMPS=NULL;
  1025.         /* wenn String als Ergebnis, diesen einrichten */
  1026.         if( kind==tokstr
  1027.             ||(kind<NUM_TOKS&&strchr(tok_strings[kind],'$')))
  1028.         {
  1029.             n.stringval=true;
  1030.             t=n.UU.sval=BASalloc(256);
  1031.         }
  1032.  
  1033.         if(kind>=REAL_TOKS)
  1034.         {
  1035.             if(kind<END_REAL)
  1036.             {
  1037.                 TEMP=realfactor(LINK);
  1038.             }
  1039.             else if(kind<END_INT)
  1040.             {
  1041.                 TEMPI=intfactor(LINK);
  1042.             }
  1043.             else if(kind<END_STRING)
  1044.             {
  1045.                 TEMPS=strfactor(LINK);
  1046.             }
  1047.         }
  1048.         switch(kind)
  1049.         {
  1050.             case toklp:
  1051.                 n = expr(LINK);
  1052.                 require(tokrp, LINK);
  1053.                 break;
  1054.             case tokminus:
  1055.                 n.UU.val = -TEMP;
  1056.                 break;
  1057.             case tokplus:
  1058.                 n.UU.val = TEMP;
  1059.                 break;
  1060.             case tokint:
  1061.                 n.UU.val = (long)TEMP;
  1062.                 break;
  1063.             case toksqu:
  1064.                 n.UU.val = TEMP * TEMP;
  1065.                 break;
  1066.             case tokrcp:
  1067.                 n.UU.val = 1./TEMP;
  1068.                 break;
  1069.             case toksqrt:
  1070.                 n.UU.val = sqrt(TEMP);
  1071.                 break;
  1072.             case toksin:
  1073.                 n.UU.val = sin(to_rad(TEMP));
  1074.                 break;
  1075.             case toksinh:
  1076.                 n.UU.val = sinh(TEMP);
  1077.                 break;
  1078.             case tokasin:
  1079.                 n.UU.val = from_rad(asin(TEMP));
  1080.                 break;
  1081.             case tokasinh:
  1082.                 n.UU.val = asinh(TEMP);
  1083.                 break;
  1084.             case tokcos:
  1085.                 n.UU.val = cos(to_rad(TEMP));
  1086.                 break;
  1087.             case tokcosh:
  1088.                 n.UU.val = cosh(TEMP);
  1089.                 break;
  1090.             case tokacos:
  1091.                 n.UU.val = from_rad(acos(TEMP));
  1092.                 break;
  1093.             case tokacosh:
  1094.                 n.UU.val = acosh(TEMP);
  1095.                 break;
  1096.              case toktan:
  1097.                 n.UU.val = tan(to_rad(TEMP));
  1098.                 break;
  1099.             case toktanh:
  1100.                 n.UU.val = tanh(TEMP);
  1101.                 break;
  1102.             case tokarctan:
  1103.                 n.UU.val = from_rad(atan(TEMP));
  1104.                 break;
  1105.             case tokatanh:
  1106.                 n.UU.val = atanh(TEMP);
  1107.                 break;
  1108.             case tokln:
  1109.                 n.UU.val = log(TEMP);
  1110.                 break;
  1111.             case tokexp:
  1112.                 n.UU.val = exp(TEMP);
  1113.                 break;
  1114.             case toklg:
  1115.                 n.UU.val = log10(TEMP);
  1116.                 break;
  1117.             case tokten:
  1118.                 n.UU.val = pow(10,TEMP);
  1119.                 break;
  1120.             case tokld:
  1121.                 n.UU.val = log(TEMP)/M_LN2;
  1122.                 break;
  1123.             case tokpow2:
  1124.                 n.UU.val = pow(2,TEMP);
  1125.                 break;
  1126.             case tokabs:
  1127.                 n.UU.val = fabs(TEMP);
  1128.                 break;
  1129.             case toksgn:
  1130.                 n.UU.val = TEMP < 0;
  1131.                 break;
  1132.             case tokstr_:
  1133.                 numtostr(n.UU.sval, TEMP);
  1134.                 break;
  1135.             case tokdms_:
  1136.                 dms(n.UU.sval, TEMP);
  1137.                 break;
  1138.             case toknot:
  1139.                 n.UU.val = ~TEMPI;
  1140.                 break;
  1141.             case tokfact:
  1142.                 TEMP=1.;
  1143.                 while(TEMPI>1) TEMP*=TEMPI--;
  1144.                 n.UU.val=TEMP;
  1145.                 break;
  1146.             case tokchr_:
  1147.                 n.UU.sval[0] = (char)TEMPI;
  1148.                 if(TEMPI==0) make0byte(n.UU.sval+1);
  1149.                 break;
  1150.             case tokbin_:
  1151.                 n.UU.sval[0]='%';
  1152.                 ultoa((unsigned long)TEMPI,n.UU.sval+1,2);
  1153.                 break;
  1154.             case tokoct_:
  1155.                 n.UU.sval[0]='&';
  1156.                 ultoa((unsigned long)TEMPI,n.UU.sval+1,8);
  1157.                 break;
  1158.             case tokhex_:
  1159.                 n.UU.sval[0]='$';
  1160.                 ultoa((unsigned long)TEMPI,n.UU.sval+1,16);
  1161.                 break;
  1162.             case tokpeekl: bytes=4; goto peek;
  1163.             case tokpeekw: bytes=2; goto peek;
  1164.             case tokpeek:  bytes=1;
  1165. peek:            adress = (char*) TEMPI;
  1166.                 n.UU.val = Supexec(peek);
  1167.                 break;
  1168.             case tokval:
  1169.                 tok1 = LINK->t;
  1170.                 parse(TEMPS, &LINK->t);
  1171.                 tok = LINK->t;
  1172.                 if (tok == NULL)
  1173.                     n.UU.val = 0.0;
  1174.                 else
  1175.                     n = expr(LINK);
  1176.                 disposetokens(&tok);
  1177.                 LINK->t = tok1;
  1178.                 break;
  1179.             case toklabel:
  1180.                 n.UU.val=TEMPI;
  1181.                 break;
  1182.             case tokdeg:
  1183.                 n.UU.val=deg(TEMPS);
  1184.                 break;
  1185.             case tokasc:
  1186.                 n.UU.val = *TEMPS;
  1187.                 break;
  1188.             case toklen:
  1189.                 n.UU.val = strlen(TEMPS);
  1190.                 break;
  1191.             case tokfsel_:
  1192.                 set_path(1);
  1193.                 if(*pfad==0)
  1194.                 {
  1195.                     *pfad=cpx_buffer[0]+'A';
  1196.                     pfad[1]=':';
  1197.                     strcpy(pfad+2,cpx_buffer+1);
  1198.                     strcat(pfad,"\\");
  1199.                 }
  1200.                 t=strrchr(pfad,'\\');
  1201.                 if(!isseparator(LINK)) TEMPS=strfactor(LINK);
  1202.                 if(t!=NULL) strcpy(t+1,TEMPS!=NULL?TEMPS:"*.*");
  1203.                 fsel_input(pfad,name,&fsel);
  1204.                 if(fsel)
  1205.                 {
  1206.                     t=n.UU.sval;
  1207.                     strcpy(t,pfad);
  1208.                     t=strrchr(t,'\\');
  1209.                     if(t!=NULL) strcpy(t+1,name);
  1210.                 }
  1211.                 set_path(0);
  1212.                 break;
  1213.             case tokrand:
  1214.                 if(!isseparator(LINK))
  1215.                 {
  1216.                     n.UU.val=Random()%intfactor(LINK);
  1217.                 }
  1218.                 else
  1219.                 {
  1220.                     n.UU.val=(double)Random()/(double)0x00FFFFFFL;
  1221.                 }
  1222.                 break;
  1223.             case tokpi:
  1224.                 n.UU.val=M_PI;
  1225.                 break;
  1226.             case tokerrno:
  1227.                 n.UU.val=fileerror;
  1228.                 fileerror=0;
  1229.                 break;
  1230.             case tokinkey_:
  1231.                     if(woff!=roff)
  1232.                     {
  1233.                             n.UU.sval[0]=KeyBuffer[roff++];
  1234.                             if(roff>=KB_SIZE) roff=0;
  1235.                     }
  1236.                     else WaitBASIC();
  1237.                     break;
  1238.             case tokpath_:
  1239.                 n.UU.sval[0]=cpx_buffer[0]+'A';
  1240.                 n.UU.sval[1]=':';
  1241.                 strcpy(t+2,cpx_buffer+1);
  1242.                 break;
  1243.             case toktime_:
  1244.                 time(&zeit);
  1245.                 strcpy(t,ctime(&zeit));
  1246.                 break;
  1247.             case toktimer:
  1248.                 n.UU.val = (double)clock();
  1249.                 break;
  1250.             case tokalert:
  1251.                 require(toklp, LINK);
  1252.                 i=intexpr(LINK);
  1253.                 require(tokcomma, LINK);
  1254.                 TEMPS=strexpr(LINK);
  1255.                 require(tokrp, LINK);
  1256.                 n.UU.val=(double)form_alert((int)i,TEMPS);
  1257.                 break;
  1258.             case tokinbyte:
  1259.                 n.UU.val=cmdinbyte(TEMPS);
  1260.                 break;
  1261.             case tokoutbyte:
  1262.                 n.UU.val=cmdoutbyte(LINK,TEMPS);
  1263.                 break;
  1264.             case tokhex:
  1265.             case tokoct:
  1266.             case tokbin:
  1267.             case tokdec:
  1268.                    n.UU.val = facttok->UU.num;
  1269.                    break;
  1270.             case tokvar:
  1271.                 LINK->t = facttok;
  1272.                 v = findvar(LINK);
  1273.                 n.stringval = v->stringvar;
  1274.                 if (n.stringval)
  1275.                 {
  1276.                     n.UU.sval = (Char *)BASalloc(256);
  1277.                     strcpy(n.UU.sval, *v->UU.U1.sval);
  1278.                 } else
  1279.                     n.UU.val = *v->UU.U0.val;
  1280.                 break;
  1281.             case tokstr:
  1282.                 strcpy(n.UU.sval, facttok->UU.sp);
  1283.                 break;
  1284.             default:
  1285.                 snerr();
  1286.         }
  1287.         if(TEMPS!=NULL) Free(TEMPS);
  1288.     }
  1289.     return n;
  1290. }
  1291.  
  1292. Local valrec upexpr( struct LOC_exec *LINK )
  1293. {
  1294.     valrec n, n2;
  1295.  
  1296.     n = factor(LINK);
  1297.     while (LINK->t != NULL && LINK->t->kind == tokup)
  1298.     {
  1299.         if (n.stringval)
  1300.             tmerr();
  1301.         LINK->t = LINK->t->next;
  1302.         n2 = upexpr(LINK);
  1303.         if (n2.stringval) tmerr();
  1304.         n.UU.val = pow(n.UU.val,n2.UU.val);
  1305.     }
  1306.     return n;
  1307. }
  1308.  
  1309. Local valrec term( struct LOC_exec *LINK )
  1310. {
  1311.     valrec n, n2;
  1312.     short k;
  1313.  
  1314.     n = upexpr(LINK);
  1315.     while (LINK->t != NULL &&
  1316.             ((k=LINK->t->kind)==toktimes||k==tokdiv||k==tokmod)
  1317.           )
  1318.     {
  1319.         LINK->t = LINK->t->next;
  1320.         n2 = upexpr(LINK);
  1321.         if (n.stringval || n2.stringval)
  1322.             tmerr();
  1323.         if (k == tokmod)
  1324.         {
  1325.             n.UU.val = (long)round(n.UU.val) % (long)round(n2.UU.val);
  1326.         } else if (k == toktimes)
  1327.             n.UU.val *= n2.UU.val;
  1328.         else
  1329.             n.UU.val /= n2.UU.val;
  1330.     }
  1331.     return n;
  1332. }
  1333.  
  1334. Local valrec sexpr( struct LOC_exec *LINK )
  1335. {
  1336.     valrec n, n2;
  1337.     short k;
  1338.  
  1339.     n = term(LINK);
  1340.     while (LINK->t != NULL &&
  1341.         ((k=LINK->t->kind)==tokplus||k==tokminus))
  1342.     {
  1343.         LINK->t = LINK->t->next;
  1344.         n2 = term(LINK);
  1345.         if (n.stringval != n2.stringval)
  1346.             tmerr();
  1347.         if (k == tokplus) {
  1348.             if (n.stringval) {
  1349.                 strcat(n.UU.sval, n2.UU.sval);
  1350.                 Free(n2.UU.sval);
  1351.             } else
  1352.                 n.UU.val += n2.UU.val;
  1353.         } else {
  1354.             if (n.stringval)
  1355.                 tmerr();
  1356.             else
  1357.                 n.UU.val -= n2.UU.val;
  1358.         }
  1359.     }
  1360.     return n;
  1361. }
  1362.  
  1363. Local valrec relexpr( struct LOC_exec *LINK )
  1364. {
  1365.     valrec n, n2;
  1366.     boolean f;
  1367.     short k;
  1368.     int erg;
  1369.     double cmp;
  1370.     
  1371.     n = sexpr(LINK);
  1372.     while (LINK->t != NULL && ((k=LINK->t->kind)<=tokne&&k>=tokeq))
  1373.     {
  1374.         k = LINK->t->kind;
  1375.         LINK->t = LINK->t->next;
  1376.         n2 = sexpr(LINK);
  1377.         if (n.stringval != n2.stringval)
  1378.             tmerr();
  1379.         if (n.stringval)
  1380.         {
  1381.             erg = strcmp(n.UU.sval, n2.UU.sval);
  1382.             Free(n.UU.sval);
  1383.             Free(n2.UU.sval);
  1384.         }
  1385.         else
  1386.         {
  1387.             cmp=n.UU.val-n2.UU.val;
  1388.             erg=0;
  1389.             if(cmp>0) erg=1;
  1390.             if(cmp<0) erg=-1;
  1391.         }
  1392.         switch(k)
  1393.         {
  1394.                case tokeq:
  1395.                 f=erg==0;break;
  1396.             case tokge:
  1397.                 f=erg>=0;break;
  1398.             case tokle:
  1399.                 f=erg<=0;break;
  1400.             case toklt:
  1401.                 f=erg<0;break;
  1402.             case tokne:
  1403.                 f=erg!=0;break;
  1404.             case tokgt:
  1405.                 f=erg>0;break;
  1406.         }
  1407.         n.stringval=false;
  1408.         n.UU.val = f;
  1409.     }
  1410.     return n;
  1411. }
  1412.  
  1413. Local valrec andexpr( struct LOC_exec *LINK )
  1414. {
  1415.     valrec n, n2;
  1416.  
  1417.     n = relexpr(LINK);
  1418.     while (LINK->t != NULL && LINK->t->kind == tokand)
  1419.     {
  1420.         LINK->t = LINK->t->next;
  1421.         n2 = relexpr(LINK);
  1422.         if (n.stringval || n2.stringval)
  1423.             tmerr();
  1424.         n.UU.val = ((long)n.UU.val) & ((long)n2.UU.val);
  1425.     }
  1426.     return n;
  1427. }
  1428.  
  1429. Local valrec expr( struct LOC_exec *LINK )
  1430. {
  1431.     valrec n, n2;
  1432.     short k;
  1433.  
  1434.     n = andexpr(LINK);
  1435.     while (LINK->t != NULL && 
  1436.             ((k=LINK->t->kind)==tokor|| k==tokxor)
  1437.           )
  1438.    {
  1439.         LINK->t = LINK->t->next;
  1440.         n2 = andexpr(LINK);
  1441.         if (n.stringval || n2.stringval)
  1442.             tmerr();
  1443.         if (k == tokor)
  1444.             n.UU.val = ((long)n.UU.val) | ((long)n2.UU.val);
  1445.         else
  1446.             n.UU.val = ((long)n.UU.val) ^ ((long)n2.UU.val);
  1447.     }
  1448.     return n;
  1449. }
  1450.  
  1451. Local Void checkextra( struct LOC_exec *LINK )
  1452. {
  1453.     if (LINK->t != NULL) errormsg("Extra information on line");
  1454. }
  1455.  
  1456. Local Void skiptoeos( struct LOC_exec *LINK )
  1457. {
  1458.     while (!iseos(LINK))
  1459.         LINK->t = LINK->t->next;
  1460. }
  1461.  
  1462. Local linerec *findline( long n)
  1463. {
  1464.     linerec *l;
  1465.  
  1466.     l = linebase;
  1467.     while (l != NULL && l->num != n)
  1468.         l = l->next;
  1469.     return l;
  1470. }
  1471.  
  1472. Local linerec *mustfindline( long n)
  1473. {
  1474.     linerec *l;
  1475.  
  1476.     l = findline(n);
  1477.     if (l == NULL)
  1478.         errormsg("Undefined line");
  1479.     return l;
  1480. }
  1481.  
  1482. Local Void cmdend( struct LOC_exec *LINK )
  1483. {
  1484.     stmtline = NULL;
  1485.     LINK->t = NULL;
  1486. }
  1487.  
  1488. Local Void cmdnew( struct LOC_exec *LINK )
  1489. {
  1490.     Anyptr p;
  1491.  
  1492.     cmdend(LINK);
  1493.     clearloops();
  1494.     restoredata();
  1495.     while (linebase != NULL) {
  1496.         p = (Anyptr)linebase->next;
  1497.         disposetokens(&linebase->txt);
  1498.         Free(linebase);
  1499.         linebase = (linerec *)p;
  1500.     }
  1501.     while (varbase != NULL) {
  1502.         p = (Anyptr)varbase->next;
  1503.         if (varbase->stringvar) {
  1504.             if (*varbase->UU.U1.sval != NULL)
  1505.                 Free(*varbase->UU.U1.sval);
  1506.         }
  1507.         Free(varbase);
  1508.         varbase = (varrec *)p;
  1509.     }
  1510. }
  1511.  
  1512. Local Void cmdlist( struct LOC_exec *LINK )
  1513. {
  1514.     linerec *l;
  1515.     long n1, n2;
  1516.     int kind;
  1517.  
  1518.     do
  1519.     {
  1520.         n1 = 0;
  1521.         n2 = LONG_MAX;
  1522.         if (LINK->t != NULL)
  1523.         {
  1524.             kind=LINK->t->kind;
  1525.              if(kind >= tokbin && kind<=tokhex)
  1526.              {
  1527.                 n1 = (long)LINK->t->UU.num;
  1528.                 LINK->t = LINK->t->next;
  1529.                 if (LINK->t == NULL || LINK->t->kind != tokminus)
  1530.                     n2 = n1;
  1531.             }
  1532.         }
  1533.         if (LINK->t != NULL && LINK->t->kind == tokminus)
  1534.         {
  1535.             LINK->t = LINK->t->next;
  1536.             if (LINK->t != NULL)
  1537.             {
  1538.                 kind=LINK->t->kind;
  1539.                 if(kind<=tokhex&&kind>=tokbin)
  1540.                 {
  1541.                     n2 = (long)LINK->t->UU.num;
  1542.                     LINK->t = LINK->t->next;
  1543.                 }
  1544.                 else
  1545.                     n2 = LONG_MAX;
  1546.             }
  1547.         }
  1548.         l = linebase;
  1549.         while (l != NULL && l->num <= n2) {
  1550.             if (l->num >= n1) {
  1551.                 Printf("%ld ", l->num);
  1552.                 listtokens(stdout, l->txt);
  1553.                 Putchar('\n');
  1554.                 if(ctrl) break;
  1555.             }
  1556.             l = l->next;
  1557.         }
  1558.         if (!iseos(LINK))
  1559.             require(tokcomma, LINK);
  1560.     } while (!iseos(LINK));
  1561. }
  1562.  
  1563. #define MYBUFSIZ (4*1024)
  1564.  
  1565. #if MYBUFSIZ<BUFSIZ
  1566. #  undef MYBUFSIZ
  1567. #  define MYBUFSIZ BUFSIZ
  1568. #endif
  1569.  
  1570. Local FILE *BUFfopen(char *ptr,char *mode)
  1571. {
  1572.     FILE *fp;
  1573.     set_path(1);
  1574.     fp=fopen(ptr,mode);
  1575.     if(fp!=NULL) setvbuf(fp,NULL,_IOFBF,MYBUFSIZ);
  1576.     set_path(0);
  1577.     return fp;
  1578. }
  1579.  
  1580. Local FILE *BASfopen(Char *ptr,char *str)
  1581. {
  1582.     FILE *fp;
  1583.     char *s,temp[256];
  1584.     strcpy(temp,ptr);
  1585.     s=strrchr(temp,'\\');
  1586.     if(s==NULL) s=temp;
  1587.     s=strrchr(s,'.');
  1588.     if(s==NULL) strcat(temp,".BAS");
  1589.     fp=BUFfopen(temp,str);
  1590.     return fp;
  1591. }
  1592.  
  1593. Local Void cmdload( boolean merging, Char *name, struct LOC_exec *LINK )
  1594. {
  1595.     FILE *f;
  1596.     tokenrec *buf;
  1597.     Char *TEMP;
  1598.     int linenum=0;
  1599.  
  1600.     if (!merging) cmdnew(LINK);
  1601.     f = BASfopen(name, "r");
  1602.     if (f == NULL) _EscIO(FileNotFound);
  1603.     while (fgets(inbuf, 256, f) != NULL)
  1604.     {
  1605.         linenum++;
  1606.         TEMP = strchr(inbuf, '\n');
  1607.         if (TEMP != NULL) *TEMP = 0;
  1608.         if(*inbuf!=0)
  1609.         {
  1610.             parseinput(&buf);
  1611.             if (curline == 0)
  1612.             {
  1613.                 Printf("Bad line %d in file\n",linenum);
  1614.                 disposetokens(&buf);
  1615.                }
  1616.         }
  1617.     }
  1618.     if (f != NULL) fclose(f);
  1619. }
  1620.  
  1621. void clearall(void)
  1622. {
  1623.     clearvars();
  1624.     clearloops();
  1625.     restoredata();
  1626. }
  1627.  
  1628. Local Void cmdrun( struct LOC_exec *LINK )
  1629. {
  1630.     linerec *l;
  1631.     long i;
  1632.     string255 s;
  1633.     int kind;
  1634.  
  1635.     l = linebase;
  1636.     if (!iseos(LINK)) {
  1637.         kind=LINK->t->kind;
  1638.         if (kind<=tokhex&&kind>=tokbin)
  1639.             l = mustfindline(intexpr(LINK));
  1640.         else {
  1641.             stringexpr(s, LINK);
  1642.             i = 0;
  1643.             if (!iseos(LINK)) {
  1644.                 require(tokcomma, LINK);
  1645.                 i = intexpr(LINK);
  1646.             }
  1647.             checkextra(LINK);
  1648.             cmdload(false, s, LINK);
  1649.             if (i == 0)
  1650.                 l = linebase;
  1651.             else
  1652.                 l = mustfindline(i);
  1653.         }
  1654.     }
  1655.     stmtline = l;
  1656.     LINK->gotoflag = true;
  1657.     clearall();
  1658. }
  1659.  
  1660. Local Void cmdsave( struct LOC_exec *LINK )
  1661. {
  1662.     FILE *f;
  1663.     linerec *l;
  1664.     Char STR1[256];
  1665.     int tok,thisins;
  1666.     long line;
  1667.  
  1668.     ins=2;
  1669.     f = BASfopen(stringexpr(STR1, LINK), "w");
  1670.     if (f == NULL)  _EscIO(FileNotFound);
  1671.     l = linebase;
  1672.     line=0;
  1673.     while (l != NULL)
  1674.     {
  1675.         if(l->num>line) line=l->num;
  1676.         l=l->next;
  1677.     }
  1678.     line=strlen(ltoa(line,STR1,10));
  1679.     l = linebase;
  1680.     while (l != NULL)
  1681.     {
  1682.         tok=l->txt->kind;
  1683.         thisins=ins;
  1684.         if(tok==toknext||tok==tokwend)
  1685.         {
  1686.             if((thisins-=2)<=0) thisins=2;
  1687.         }
  1688.         FPRINTF(f, "%-*ld%*c",(int)line,l->num,thisins,' ');
  1689.         listtokens(f, l->txt);
  1690.         PUTC('\n', f);
  1691.         l = l->next;
  1692.     }
  1693.     if (f != NULL) fclose(f);
  1694. }
  1695.  
  1696. Local Void cmddel( struct LOC_exec *LINK )
  1697. {
  1698.     linerec *l, *l0, *l1;
  1699.     long n1, n2;
  1700.     int kind;
  1701.  
  1702.     do {
  1703.         if (iseos(LINK))
  1704.             snerr();
  1705.         n1 = 0;
  1706.         n2 = LONG_MAX;
  1707.         if (LINK->t != NULL)
  1708.         {
  1709.             kind=LINK->t->kind;
  1710.             if( kind<=tokhex&&kind>=tokbin )
  1711.             {
  1712.                 n1 = (long)LINK->t->UU.num;
  1713.                 LINK->t = LINK->t->next;
  1714.                 if (LINK->t == NULL || LINK->t->kind != tokminus)
  1715.                     n2 = n1;
  1716.             }
  1717.         }
  1718.         if (LINK->t != NULL && LINK->t->kind == tokminus) {
  1719.             LINK->t = LINK->t->next;
  1720.             if (LINK->t != NULL)
  1721.             {
  1722.                 kind=LINK->t->kind;
  1723.                 if(kind<=tokhex&&kind>=tokbin)
  1724.                 {
  1725.                     n2 = (long)LINK->t->UU.num;
  1726.                     LINK->t = LINK->t->next;
  1727.                 } else
  1728.                     n2 = LONG_MAX;
  1729.             }
  1730.         }
  1731.         l = linebase;
  1732.         l0 = NULL;
  1733.         while (l != NULL && l->num <= n2) {
  1734.             l1 = l->next;
  1735.             if (l->num >= n1) {
  1736.                 if (l == stmtline) {
  1737.                     cmdend(LINK);
  1738.                     clearloops();
  1739.                     restoredata();
  1740.                 }
  1741.                 if (l0 == NULL)
  1742.                     linebase = l->next;
  1743.                 else
  1744.                     l0->next = l->next;
  1745.                 disposetokens(&l->txt);
  1746.                 Free(l);
  1747.             } else
  1748.                 l0 = l;
  1749.             l = l1;
  1750.         }
  1751.         if (!iseos(LINK))
  1752.             require(tokcomma, LINK);
  1753.     } while (!iseos(LINK));
  1754. }
  1755.  
  1756. Local Void cmdrenum( struct LOC_exec *LINK )
  1757. {
  1758.     linerec *l, *l1;
  1759.     tokenrec *tok;
  1760.     long lnum, step;
  1761.  
  1762.     lnum = 10;
  1763.     step = 10;
  1764.     if (!iseos(LINK)) {
  1765.         lnum = intexpr(LINK);
  1766.         if (!iseos(LINK)) {
  1767.             require(tokcomma, LINK);
  1768.             step = intexpr(LINK);
  1769.         }
  1770.     }
  1771.     l = linebase;
  1772.     if (l == NULL)
  1773.         return;
  1774.     while (l != NULL) {
  1775.         l->num2 = lnum;
  1776.         lnum += step;
  1777.         l = l->next;
  1778.     }
  1779.     l = linebase;
  1780.     do {
  1781.         tok = l->txt;
  1782.         do {
  1783.             if (tok->kind == tokdel || tok->kind == tokrestore ||
  1784.                 tok->kind == toklist || tok->kind == tokrun ||
  1785.                 tok->kind == tokelse || tok->kind == tokthen ||
  1786.                 tok->kind == tokgosub || tok->kind == tokgoto ||
  1787.                 tok->kind == toklabel)
  1788.             {
  1789.                 while (tok->next != NULL && tok->next->kind >= tokbin
  1790.                             && tok->next->kind <= tokhex)
  1791.                 {
  1792.                     tok = tok->next;
  1793.                     lnum = (long)round(tok->UU.num);
  1794.                     l1 = linebase;
  1795.                     while (l1 != NULL && l1->num != lnum)
  1796.                         l1 = l1->next;
  1797.                     if (l1 == NULL)
  1798.                         Printf("Undefined line %ld in line %ld\n", lnum, l->num2);
  1799.                     else
  1800.                         tok->UU.num = l1->num2;
  1801.                     if (tok->next != NULL && tok->next->kind == tokcomma)
  1802.                         tok = tok->next;
  1803.                 }
  1804.             }
  1805.             tok = tok->next;
  1806.         } while (tok != NULL);
  1807.         l = l->next;
  1808.     } while (l != NULL);
  1809.     l = linebase;
  1810.     while (l != NULL) {
  1811.         l->num = l->num2;
  1812.         l = l->next;
  1813.     }
  1814. }
  1815.  
  1816. int skipcomma(struct LOC_exec *LINK)
  1817. {
  1818.     int kind;
  1819.     if(LINK->t!=NULL)
  1820.     {
  1821.         kind=LINK->t->kind;
  1822.         if(kind==toksemi||kind==tokcomma)
  1823.         {
  1824.             LINK->t=LINK->t->next;
  1825.             return 1;
  1826.         }
  1827.     }
  1828.     return 0;
  1829. }
  1830.  
  1831. Local Void cmdprint(FILE *fp, struct LOC_exec *LINK )
  1832. {
  1833.     boolean semiflag;
  1834.     valrec n;
  1835.     Char STR1[256],*s,*format,*ptr,save;
  1836.  
  1837.     while (1)
  1838.     {
  1839.         semiflag = skipcomma(LINK);
  1840.         if(iseos(LINK)) break;
  1841.         n = expr(LINK);
  1842.         if (n.stringval)
  1843.         {
  1844.             if((ptr=s=n.UU.sval)!=NULL)
  1845.             {
  1846.                 format="%*.*s";
  1847.                 if(useleft_) format="%-*.*s";
  1848.                 while(1)
  1849.                    {
  1850.                     while(*ptr++);
  1851.                     save=*ptr;
  1852.                     *ptr=0;
  1853.                     FPRINTF(fp,format,usewidth_,useprec_,s);
  1854.                     *ptr=save;
  1855.                     if(!binary || !is0byte(ptr)) break;
  1856.                     PUTC(0,fp);
  1857.                     s=ptr+4;
  1858.                 }
  1859.                 Free(n.UU.sval);
  1860.             }
  1861.         }
  1862.         else
  1863.         {
  1864.             format="%*s ";
  1865.             if(useleft) format="%-*s ";
  1866.             FPRINTF(fp,format,usewidth>0?usewidth-1:1
  1867.                     ,numtostr(STR1, n.UU.val));
  1868.         }
  1869.     }
  1870.     if (!semiflag) PUTC('\n',fp);
  1871. }
  1872.  
  1873. Local Void cmdinput(FILE *fp, struct LOC_exec *LINK )
  1874. {
  1875.     varrec *v;
  1876.     string255 s;
  1877.     tokenrec *tok, *tok0, *tok1;
  1878.     boolean strflag;
  1879.     char *prompt;
  1880.  
  1881.        tok=tok0=NULL;
  1882.     while (1)
  1883.     {
  1884.         prompt="? ";
  1885.         if (LINK->t != NULL && LINK->t->kind == tokstr)
  1886.         {
  1887.             prompt=LINK->t->UU.sp;
  1888.             LINK->t = LINK->t->next;
  1889.             skipcomma(LINK);
  1890.         }
  1891.         v = findvar(LINK);
  1892.         strflag=v->stringvar;
  1893.         while(tok == NULL)
  1894.         {
  1895.             disposetokens(&tok0);
  1896.                if(fp==stdin) Printf("%s",prompt);
  1897.             FGets(fp,s);
  1898.             if(ctrl) return;
  1899.             if(fileerror&&fp!=stdin)
  1900.             {
  1901.                 s[0]=0;
  1902.                 if(!strflag)
  1903.                 {
  1904.                     s[0]='0';
  1905.                     s[1]=0;
  1906.                 }
  1907.             }
  1908.             if(strflag) break;
  1909.                parse(s, &tok);
  1910.                tok0 = tok;
  1911.         }
  1912.         if(strflag)
  1913.         {
  1914.             if (*v->UU.U1.sval != NULL)
  1915.                 Free(*v->UU.U1.sval);
  1916.             *v->UU.U1.sval = (Char *)BASalloc(256);
  1917.             strcpy(*v->UU.U1.sval, s);
  1918.         }
  1919.         else
  1920.         {
  1921.             tok1 = LINK->t;
  1922.             LINK->t = tok;
  1923.             *v->UU.U0.val = realexpr(LINK);
  1924.             if (LINK->t != NULL)
  1925.             {
  1926.                 if (LINK->t->kind == tokcomma)
  1927.                     LINK->t = LINK->t->next;
  1928.             }
  1929.             tok = LINK->t;
  1930.             LINK->t = tok1;
  1931.         }
  1932.         if (iseos(LINK)) break;
  1933.         skipcomma(LINK);
  1934.     }
  1935.     disposetokens(&tok0);
  1936. }
  1937.  
  1938. Local Void cmdlet( boolean implied, struct LOC_exec *LINK )
  1939. {
  1940.     varrec *v;
  1941.     Char *old;
  1942.  
  1943.     if (implied) LINK->t = stmttok;
  1944.     v = findvar(LINK);
  1945.     require(tokeq, LINK);
  1946.     if (!v->stringvar)
  1947.     {
  1948.         *v->UU.U0.val = realexpr(LINK);
  1949.         return;
  1950.     }
  1951.     old = *v->UU.U1.sval;
  1952.     *v->UU.U1.sval = strexpr(LINK);
  1953.     if (old != NULL) Free(old);
  1954. }
  1955.  
  1956. Local Void cmdgoto( struct LOC_exec *LINK )
  1957. {
  1958.     stmtline = mustfindline(intexpr(LINK));
  1959.     LINK->t = NULL;
  1960.     LINK->gotoflag = true;
  1961. }
  1962.  
  1963. Local Void cmdif( struct LOC_exec *LINK )
  1964. {
  1965.     double n;
  1966.     long i;
  1967.     int kind;
  1968.  
  1969.     n = realexpr(LINK);
  1970.     require(tokthen, LINK);
  1971.     if (n == 0)
  1972.     {
  1973.         i = 0;
  1974.         do {
  1975.             if (LINK->t != NULL) {
  1976.                 if (LINK->t->kind == tokif)
  1977.                     i++;
  1978.                 if (LINK->t->kind == tokelse)
  1979.                     i--;
  1980.                 LINK->t = LINK->t->next;
  1981.             }
  1982.         } while (LINK->t != NULL && i >= 0);
  1983.     }
  1984.     if (LINK->t != NULL)
  1985.     {
  1986.         kind=LINK->t->kind;
  1987.         if(kind >= tokbin && kind <= tokhex)
  1988.             cmdgoto(LINK);
  1989.         else
  1990.             LINK->elseflag = true;
  1991.     }
  1992. }
  1993.  
  1994. Local Void cmdelse( struct LOC_exec *LINK )
  1995. {
  1996.     LINK->t = NULL;
  1997. }
  1998.  
  1999. Local boolean skiploop( short up, short dn, struct LOC_exec *LINK )
  2000. {
  2001.     boolean Result;
  2002.     long i;
  2003.     linerec *saveline;
  2004.  
  2005.     saveline = stmtline;
  2006.     i = 0;
  2007.     do {
  2008.         while (LINK->t == NULL) {
  2009.             if (stmtline == NULL || stmtline->next == NULL) {
  2010.                 Result = false;
  2011.                 stmtline = saveline;
  2012.                 goto _L1;
  2013.             }
  2014.             stmtline = stmtline->next;
  2015.             LINK->t = stmtline->txt;
  2016.         }
  2017.         if (LINK->t->kind == up)
  2018.             i++;
  2019.         if (LINK->t->kind == dn)
  2020.             i--;
  2021.         LINK->t = LINK->t->next;
  2022.     } while (i >= 0);
  2023.     Result = true;
  2024. _L1:
  2025.     return Result;
  2026. }
  2027.  
  2028. Local Void cmdfor( struct LOC_exec *LINK )
  2029. {
  2030.     looprec *l, lr;
  2031.     linerec *saveline;
  2032.     long i, j;
  2033.  
  2034.     lr.UU.U0.vp = findvar(LINK);
  2035.     if (lr.UU.U0.vp->stringvar)
  2036.         snerr();
  2037.     require(tokeq, LINK);
  2038.     *lr.UU.U0.vp->UU.U0.val = realexpr(LINK);
  2039.     require(tokto, LINK);
  2040.     lr.UU.U0.max = realexpr(LINK);
  2041.     if (LINK->t != NULL && LINK->t->kind == tokstep) {
  2042.         LINK->t = LINK->t->next;
  2043.         lr.UU.U0.step = realexpr(LINK);
  2044.     } else
  2045.         lr.UU.U0.step = 1.0;
  2046.     lr.homeline = stmtline;
  2047.     lr.hometok = LINK->t;
  2048.     lr.kind = forloop;
  2049.     lr.next = loopbase;
  2050.     if (lr.UU.U0.step >= 0 && *lr.UU.U0.vp->UU.U0.val > lr.UU.U0.max ||
  2051.         lr.UU.U0.step <= 0 && *lr.UU.U0.vp->UU.U0.val < lr.UU.U0.max) {
  2052.         saveline = stmtline;
  2053.         i = 0;
  2054.         j = 0;
  2055.         do {
  2056.             while (LINK->t == NULL) {
  2057.                 if (stmtline == NULL || stmtline->next == NULL) {
  2058.                     stmtline = saveline;
  2059.                     errormsg("FOR without NEXT");
  2060.                 }
  2061.                 stmtline = stmtline->next;
  2062.                 LINK->t = stmtline->txt;
  2063.             }
  2064.             if (LINK->t->kind == tokfor) {
  2065.                 if (LINK->t->next != NULL && LINK->t->next->kind == tokvar &&
  2066.                     LINK->t->next->UU.vp == lr.UU.U0.vp)
  2067.                     j++;
  2068.                 else
  2069.                     i++;
  2070.             }
  2071.             if (LINK->t->kind == toknext) {
  2072.                 if (LINK->t->next != NULL && LINK->t->next->kind == tokvar &&
  2073.                     LINK->t->next->UU.vp == lr.UU.U0.vp)
  2074.                     j--;
  2075.                 else
  2076.                     i--;
  2077.             }
  2078.             LINK->t = LINK->t->next;
  2079.         } while (i >= 0 && j >= 0);
  2080.         skiptoeos(LINK);
  2081.         return;
  2082.     }
  2083.     l = (looprec *)BASalloc(sizeof(looprec));
  2084.     *l = lr;
  2085.     loopbase = l;
  2086. }
  2087.  
  2088. Local Void cmdnext( struct LOC_exec *LINK )
  2089. {
  2090.     varrec *v;
  2091.     boolean found;
  2092.     looprec *l, *WITH;
  2093.  
  2094.     if (!iseos(LINK))
  2095.         v = findvar(LINK);
  2096.     else
  2097.         v = NULL;
  2098.     do {
  2099.         if (loopbase == NULL || loopbase->kind == gosubloop)
  2100.             errormsg("NEXT without FOR");
  2101.         found = (loopbase->kind == forloop &&
  2102.             (v == NULL || loopbase->UU.U0.vp == v));
  2103.         if (!found) {
  2104.             l = loopbase->next;
  2105.             Free(loopbase);
  2106.             loopbase = l;
  2107.         }
  2108.     } while (!found);
  2109.     WITH = loopbase;
  2110.     *WITH->UU.U0.vp->UU.U0.val += WITH->UU.U0.step;
  2111.     if ((WITH->UU.U0.step < 0 || *WITH->UU.U0.vp->UU.U0.val <= WITH->UU.U0.max) &&
  2112.         (WITH->UU.U0.step > 0 || *WITH->UU.U0.vp->UU.U0.val >= WITH->UU.U0.max)) {
  2113.         stmtline = WITH->homeline;
  2114.         LINK->t = WITH->hometok;
  2115.         return;
  2116.     }
  2117.     l = loopbase->next;
  2118.     Free(loopbase);
  2119.     loopbase = l;
  2120. }
  2121.  
  2122. Local Void cmdwhile( struct LOC_exec *LINK )
  2123. {
  2124.     looprec *l;
  2125.  
  2126.     l = (looprec *)BASalloc(sizeof(looprec));
  2127.     l->next = loopbase;
  2128.     loopbase = l;
  2129.     l->kind = whileloop;
  2130.     l->homeline = stmtline;
  2131.     l->hometok = LINK->t;
  2132.     if (iseos(LINK))
  2133.         return;
  2134.     if (realexpr(LINK) != 0)
  2135.         return;
  2136.     if (!skiploop(tokwhile, tokwend, LINK))
  2137.         errormsg("WHILE without WEND");
  2138.     l = loopbase->next;
  2139.     Free(loopbase);
  2140.     loopbase = l;
  2141.     skiptoeos(LINK);
  2142. }
  2143.  
  2144. Local Void cmdwend( struct LOC_exec *LINK )
  2145. {
  2146.     tokenrec *tok;
  2147.     linerec *tokline;
  2148.     looprec *l;
  2149.     boolean found;
  2150.  
  2151.     do {
  2152.         if (loopbase == NULL || loopbase->kind == gosubloop)
  2153.             errormsg("WEND without WHILE");
  2154.         found = (loopbase->kind == whileloop);
  2155.         if (!found) {
  2156.             l = loopbase->next;
  2157.             Free(loopbase);
  2158.             loopbase = l;
  2159.         }
  2160.     } while (!found);
  2161.     if (!iseos(LINK)) {
  2162.         if (realexpr(LINK) != 0)
  2163.             found = false;
  2164.     }
  2165.     tok = LINK->t;
  2166.     tokline = stmtline;
  2167.     if (found) {
  2168.         stmtline = loopbase->homeline;
  2169.         LINK->t = loopbase->hometok;
  2170.         if (!iseos(LINK)) {
  2171.             if (realexpr(LINK) == 0)
  2172.                 found = false;
  2173.         }
  2174.     }
  2175.     if (found)
  2176.         return;
  2177.     LINK->t = tok;
  2178.     stmtline = tokline;
  2179.     l = loopbase->next;
  2180.     Free(loopbase);
  2181.     loopbase = l;
  2182. }
  2183.  
  2184. Local Void cmdgosub( struct LOC_exec *LINK )
  2185. {
  2186.     looprec *l;
  2187.  
  2188.     l = (looprec *)BASalloc(sizeof(looprec));
  2189.     l->next = loopbase;
  2190.     loopbase = l;
  2191.     l->kind = gosubloop;
  2192.     l->homeline = stmtline;
  2193.     l->hometok = LINK->t;
  2194.     cmdgoto(LINK);
  2195. }
  2196.  
  2197. Local Void cmdreturn( struct LOC_exec *LINK )
  2198. {
  2199.     looprec *l;
  2200.     boolean found;
  2201.  
  2202.     do {
  2203.         if (loopbase == NULL)
  2204.             errormsg("RETURN without GOSUB");
  2205.         found = (loopbase->kind == gosubloop);
  2206.         if (!found) {
  2207.             l = loopbase->next;
  2208.             Free(loopbase);
  2209.             loopbase = l;
  2210.         }
  2211.     } while (!found);
  2212.     stmtline = loopbase->homeline;
  2213.     LINK->t = loopbase->hometok;
  2214.     l = loopbase->next;
  2215.     Free(loopbase);
  2216.     loopbase = l;
  2217.     skiptoeos(LINK);
  2218. }
  2219.  
  2220. Local Void cmdread( struct LOC_exec *LINK )
  2221. {
  2222.     varrec *v;
  2223.     tokenrec *tok;
  2224.     boolean found;
  2225.  
  2226.     do {
  2227.         v = findvar(LINK);
  2228.         tok = LINK->t;
  2229.         LINK->t = datatok;
  2230.         if (dataline == NULL) {
  2231.             dataline = linebase;
  2232.             LINK->t = dataline->txt;
  2233.         }
  2234.         if (LINK->t == NULL || LINK->t->kind != tokcomma) {
  2235.             do {
  2236.                 while (LINK->t == NULL) {
  2237.                     if (dataline == NULL || dataline->next == NULL)
  2238.                         errormsg("Out of Data");
  2239.                     dataline = dataline->next;
  2240.                     LINK->t = dataline->txt;
  2241.                 }
  2242.                 found = (LINK->t->kind == tokdata);
  2243.                 LINK->t = LINK->t->next;
  2244.             } while (!found || iseos(LINK));
  2245.         } else
  2246.             LINK->t = LINK->t->next;
  2247.         if (v->stringvar) {
  2248.             if (*v->UU.U1.sval != NULL)
  2249.                 Free(*v->UU.U1.sval);
  2250.             *v->UU.U1.sval = strexpr(LINK);
  2251.         } else
  2252.             *v->UU.U0.val = realexpr(LINK);
  2253.         datatok = LINK->t;
  2254.         LINK->t = tok;
  2255.         if (!iseos(LINK))
  2256.             require(tokcomma, LINK);
  2257.     } while (!iseos(LINK));
  2258. }
  2259.  
  2260. Local Void cmddata( struct LOC_exec *LINK )
  2261. {
  2262.     skiptoeos(LINK);
  2263. }
  2264.  
  2265. Local Void cmdrestore( struct LOC_exec *LINK )
  2266. {
  2267.     if (iseos(LINK))
  2268.         restoredata();
  2269.     else {
  2270.         dataline = mustfindline(intexpr(LINK));
  2271.         datatok = dataline->txt;
  2272.     }
  2273. }
  2274.  
  2275. Local Void cmdgotoxy( struct LOC_exec *LINK )
  2276. {
  2277.     long x,y;
  2278.  
  2279.     x = intexpr(LINK);
  2280.     require(tokcomma, LINK);
  2281.     y = intexpr(LINK);
  2282.  
  2283.     Putchar(27);
  2284.     Putchar('Y');
  2285.     Putchar(32+(int)x);
  2286.     Putchar(32+(int)y);
  2287.  
  2288. }
  2289.  
  2290. Local Void cmdon( struct LOC_exec *LINK )
  2291. {
  2292.     long i;
  2293.     looprec *l;
  2294.  
  2295.     i = intexpr(LINK);
  2296.     if (LINK->t != NULL && LINK->t->kind == tokgosub) {
  2297.         l = (looprec *)BASalloc(sizeof(looprec));
  2298.         l->next = loopbase;
  2299.         loopbase = l;
  2300.         l->kind = gosubloop;
  2301.         l->homeline = stmtline;
  2302.         l->hometok = LINK->t;
  2303.         LINK->t = LINK->t->next;
  2304.     } else
  2305.         require(tokgoto, LINK);
  2306.     if (i < 1) {
  2307.         skiptoeos(LINK);
  2308.         return;
  2309.     }
  2310.     while (i > 1 && !iseos(LINK)) {
  2311.         require(tokdec, LINK);
  2312.         if (!iseos(LINK))
  2313.             require(tokcomma, LINK);
  2314.         i--;
  2315.     }
  2316.     if (!iseos(LINK))
  2317.         cmdgoto(LINK);
  2318. }
  2319.  
  2320. Local Void cmddim( struct LOC_exec *LINK )
  2321. {
  2322.     long i, j, k;
  2323.     varrec *v;
  2324.     boolean done;
  2325.  
  2326.     do {
  2327.         if (LINK->t == NULL || LINK->t->kind != tokvar)
  2328.             snerr();
  2329.         v = LINK->t->UU.vp;
  2330.         LINK->t = LINK->t->next;
  2331.         if (v->numdims != 0) 
  2332.             errormsg("Array already dimensioned");
  2333.         j = 1;
  2334.         i = 0;
  2335.         require(toklp, LINK);
  2336.         do {
  2337.             k = intexpr(LINK) + 1;
  2338.             if (k < 1)
  2339.                 badsubscr();
  2340.             if (i >= maxdims)
  2341.                 badsubscr();
  2342.             i++;
  2343.             v->dims[i - 1] = k;
  2344.             j *= k;
  2345.             done = (LINK->t != NULL && LINK->t->kind == tokrp);
  2346.             if (!done)
  2347.                 require(tokcomma, LINK);
  2348.         } while (!done);
  2349.         LINK->t = LINK->t->next;
  2350.         v->numdims = i;
  2351.  
  2352.         if (v->stringvar) j*=sizeof(char*);
  2353.         else j*=sizeof(double);
  2354.  
  2355.         v->UU.U1.sarr = (Char **)BASalloc(j);
  2356.  
  2357.         if (!iseos(LINK)) require(tokcomma, LINK);
  2358.     } while (!iseos(LINK));
  2359. }
  2360.  
  2361. void poke(void)
  2362. {
  2363.     register d=bytes;
  2364.     register char *s=adress,*t=(char*)&wert+4-d;
  2365.     peekpoke(t,s,d);
  2366. }
  2367.  
  2368. Local Void cmdpoke( struct LOC_exec *LINK )
  2369. {
  2370.     adress = (char*)intexpr(LINK);
  2371.     require(tokcomma, LINK);
  2372.     wert=intexpr(LINK);
  2373.  
  2374.     Supexec((long(*)(void))poke);
  2375. }
  2376.  
  2377. Local Void cmdusing(struct LOC_exec *LINK,int string)
  2378. {
  2379.     int i;
  2380.     int *wp,*pp,*lp;
  2381.     if(string)
  2382.     {
  2383.         wp=&usewidth_;
  2384.         pp=&useprec_;
  2385.         lp=&useleft_;
  2386.         *pp=255;
  2387.     }
  2388.     else
  2389.     {
  2390.         wp=&usewidth;
  2391.         pp=&useprec;
  2392.         lp=&useleft;
  2393.         *pp=10;
  2394.     }    
  2395.     *wp=0;
  2396.     *lp=0;
  2397.     if(!iseos(LINK))
  2398.     {
  2399.         if(LINK->t->kind!=tokcomma)
  2400.         {
  2401.             *pp=(int)intexpr(LINK);
  2402.         }
  2403.         if(!iseos(LINK)&&LINK->t->kind==tokcomma)
  2404.         {
  2405.             LINK->t=LINK->t->next;
  2406.             i=(int)intexpr(LINK);
  2407.             if(i<0)
  2408.             {
  2409.                 *lp=1;
  2410.                 i=-i;
  2411.             }
  2412.             *wp=i;
  2413.         }
  2414.     }
  2415. }
  2416.  
  2417. Local Void cmdplot(struct LOC_exec *LINK)
  2418. {
  2419.     int x,y;
  2420.     x=(int)intexpr(LINK);
  2421.     require(tokcomma,LINK);
  2422.     y=(int)intexpr(LINK);
  2423.     plotpoint(x,y);
  2424. }
  2425.     
  2426. Local Void cmdline(struct LOC_exec *LINK)
  2427. {
  2428.     int x0,y0,x1,y1;
  2429.     x0=(int)intexpr(LINK);
  2430.     require(tokcomma,LINK);
  2431.     y0=(int)intexpr(LINK);
  2432.     require(tokcomma,LINK);
  2433.     x1=(int)intexpr(LINK);
  2434.     require(tokcomma,LINK);
  2435.     y1=(int)intexpr(LINK);
  2436.     line(x0,y0,x1,y1);
  2437. }
  2438.  
  2439.  
  2440. /* Routinen zur Dateiverwaltung:
  2441. ** Es wird nach jedem Lesen und Schreiben die Datei physikalisch geschlossen,
  2442. ** d.h. FOPEN und FCLOSE setzen lediglich Dateinamen und Leseposition
  2443. ** Damit das nicht zu langsam wird, erfolgt das Schließen 10 Timer (1/2 sek.)
  2444. ** nach dem letzten Zugriff, bzw. bie FCLOSE.
  2445. ** DATAfclose schließt die Datei in Abhängigkeit vom übergebenen Parameter
  2446. ** oder der verstrichenen Zeit,
  2447. ** DATAfopen übergibt den bereits eingerichteten Dateizeiger oder öffnet
  2448. ** sonst die Datei und stellt alle Parameter zu Bufferung ein.
  2449. */
  2450.  
  2451. Local FILE *thefp;
  2452. Local int rw_mode;
  2453. int fptime;
  2454.  
  2455. /* mode<>0 lesen, ==0 schreiben */
  2456. void DATAfclose(int doit)
  2457. {
  2458.     if(thefp!=NULL)
  2459.     {
  2460.         if(doit||fptime<=0)
  2461.         {
  2462.             if(rw_mode!=0) fileposition=ftell(thefp);
  2463.             fclose(thefp);
  2464.             thefp=NULL;
  2465.             fptime=0;
  2466.         }
  2467.     }
  2468. }
  2469.  
  2470. /* mode<>0 lesen, ==0 schreiben */
  2471. Local FILE *DATAfopen(int mode)
  2472. {
  2473.     char *modus="a";
  2474.     if(mode) modus="r";
  2475.     if(binary)
  2476.     {
  2477.         modus="ab";
  2478.         if(mode) modus="rb";
  2479.     }
  2480.     if(mode!=rw_mode) DATAfclose(1);
  2481.     if(thefp==NULL)
  2482.     {
  2483.         thefp=BUFfopen(filename,modus);
  2484.         if(thefp!=NULL&&mode!=0) fseek(thefp,fileposition,SEEK_SET);
  2485.         rw_mode=mode;
  2486.     }
  2487.     fptime=10;
  2488.     return thefp;
  2489. }
  2490.  
  2491. Local Void cmdcircle(struct LOC_exec *LINK)
  2492. {
  2493.     int x0,y0,r;
  2494.     x0=(int)intexpr(LINK);
  2495.     require(tokcomma,LINK);
  2496.     y0=(int)intexpr(LINK);
  2497.     require(tokcomma,LINK);
  2498.     r=(int)intexpr(LINK);
  2499.     circle(x0,y0,r);
  2500. }
  2501.  
  2502. Local Void cmddir( struct LOC_exec *LINK, int command )
  2503. {
  2504.     Char    STR1[256];
  2505.  
  2506.     set_path(1);
  2507.     stringexpr(STR1, LINK);
  2508.     
  2509.     if(STR1[1]==':') Dsetdrv(toupper(*STR1) - 'A');
  2510.         
  2511.     switch(command)
  2512.     {
  2513.         case MKDIR:
  2514.             if(Dcreate(STR1))
  2515.                 Printf("Can't create folder\n");
  2516.             break;
  2517.         case RMDIR:
  2518.             if(Ddelete(STR1))
  2519.                 Printf("Can't delete folder\n"); 
  2520.             break;
  2521.         case CHDIR:
  2522.             if(Dsetpath(STR1))
  2523.             {
  2524.                 Printf("Can't change to folder\n");
  2525.             }
  2526.             else
  2527.             {
  2528.                 cpx_buffer[0]=Dgetdrv();
  2529.                 Dgetpath(cpx_buffer+1,0);
  2530.             }
  2531.             break;
  2532.     }
  2533.  
  2534.     set_path(0);
  2535. }
  2536.  
  2537. DTA dta;
  2538.  
  2539. Local Void fileprt(void)
  2540. {
  2541.     char *ff_name=dta.d_fname;
  2542.     char *p=ff_name;
  2543.  
  2544.     while(*p&&*p!='.') p++;
  2545.  
  2546.      if(p[0]!=0)
  2547.      {
  2548.          if(p[1]=='.'||p[1]==0) p="";
  2549.          else *p++=0;
  2550.      }
  2551.  
  2552.     if (dta.d_attrib & 0x10)
  2553.         Printf("%-10s%-6s%10s\n",ff_name,p,"<SUB-DIR>");
  2554.     else
  2555.         Printf("%-10s%-6s%10ld\n",ff_name,p,dta.d_length);
  2556.     WaitBASIC();
  2557. }
  2558.  
  2559. Local Void cmdfiles( struct LOC_exec *LINK )
  2560. {
  2561.     Char    STR1[256];
  2562.     DTA    *olddta=Fgetdta();
  2563.     Fsetdta(&dta);
  2564.     
  2565.     set_path(1);
  2566.     if (iseos( LINK ))
  2567.         strcpy(STR1, "*.*");
  2568.     else
  2569.         stringexpr(STR1, LINK);
  2570.  
  2571.     if(Fsfirst(STR1,0x31)==0)
  2572.     {
  2573.         do
  2574.         {
  2575.             fileprt();
  2576.         }
  2577.         while(Fsnext()==0);
  2578.     }
  2579.     else
  2580.     {
  2581.         Printf("No files found\n");
  2582.     }
  2583.     set_path(0);
  2584.     Fsetdta(olddta);
  2585. }
  2586.  
  2587. Static Void exec( Void )
  2588. {
  2589.     struct LOC_exec V;
  2590.     contsave *cont=&contvar;
  2591.     Char *ioerrmsg;
  2592.     Char STR1[256],*s,*p;
  2593.     FILE *fp;
  2594.  
  2595.     TRY(try1);
  2596.     do
  2597.     {
  2598.         do
  2599.         {
  2600.             V.gotoflag = false;
  2601.             V.elseflag = false;
  2602.             while (stmttok != NULL && stmttok->kind == tokcolon)
  2603.                 stmttok = stmttok->next;
  2604.  
  2605.             V.t = stmttok;
  2606.             if (V.t != NULL)
  2607.             {
  2608.                 V.t = V.t->next;
  2609.                 switch (stmttok->kind)
  2610.                 {
  2611.                 case tokrem: /* blank case */
  2612.                     break;
  2613.  
  2614.                 case toktron:
  2615.                     tron=true;
  2616.                     break;
  2617.  
  2618.                 case toktroff:
  2619.                     tron=false;
  2620.                     break;
  2621.  
  2622.                 case toklist:
  2623.                     cmdlist(&V);
  2624.                     break;
  2625.  
  2626.                 case tokrun:
  2627.                     cmdrun(&V);
  2628.                     break;
  2629.  
  2630.                 case toknew:
  2631.                     cmdnew(&V);
  2632.                     break;
  2633.  
  2634.                 case tokload:
  2635.                     cmdload(false, stringexpr(STR1, &V), &V);
  2636.                     break;
  2637.  
  2638.                 case tokmerge:
  2639.                     cmdload(true, stringexpr(STR1, &V), &V);
  2640.                     break;
  2641.  
  2642.                 case toksave:
  2643.                     cmdsave(&V);
  2644.                     break;
  2645.  
  2646.                 case tokfiles:
  2647.                     cmdfiles(&V);
  2648.                     break;
  2649.  
  2650.                 case tokchdir:
  2651.                     cmddir(&V,CHDIR);
  2652.                     break;
  2653.                     
  2654.                 case tokmkdir:
  2655.                     cmddir(&V,MKDIR);
  2656.                     break;
  2657.                     
  2658.                 case tokrmdir:
  2659.                     cmddir(&V,RMDIR);
  2660.                     break;
  2661.  
  2662.                 case tokbye:
  2663.                     exitflag = true;
  2664.                     break;
  2665.  
  2666.                 case tokdel:
  2667.                     cmddel(&V);
  2668.                     break;
  2669.  
  2670.                 case tokrenum:
  2671.                     cmdrenum(&V);
  2672.                     break;
  2673.  
  2674.                 case toklet:
  2675.                     cmdlet(false, &V);
  2676.                     break;
  2677.  
  2678.                 case tokvar:
  2679.                     cmdlet(true, &V);
  2680.                     break;
  2681.  
  2682.                 case tokprint:
  2683.                     cmdprint(stdout,&V);
  2684.                     break;
  2685.  
  2686.                 case tokfprint:
  2687.                     fp=stdout;
  2688.                     if(*filename)
  2689.                     {
  2690.                         fp=DATAfopen(0);
  2691. #ifndef REDEFD
  2692.                         if(fp==NULL) fp=stdout;
  2693. #endif
  2694.                     }
  2695.                     cmdprint(fp,&V);
  2696.                     break;
  2697.  
  2698.                 case tokinput:
  2699.                     cmdinput(stdin,&V);
  2700.                     break;
  2701.  
  2702.                 case tokfinput:
  2703.                     fp=stdin;
  2704.                     if(*filename)
  2705.                     {
  2706.                         fp=DATAfopen(1);
  2707. #ifndef REDEFD
  2708.                         if(fp==NULL) fp=stdin;
  2709. #endif
  2710.                     }
  2711.                     cmdinput(fp,&V);
  2712.                     break;
  2713.  
  2714.                 case tokgoto:
  2715.                     cmdgoto(&V);
  2716.                     break;
  2717.  
  2718.                 case tokif:
  2719.                     cmdif(&V);
  2720.                     break;
  2721.  
  2722.                 case tokelse:
  2723.                     cmdelse(&V);
  2724.                     break;
  2725.  
  2726.                 case tokend:
  2727.                     cmdend(&V);
  2728.                     break;
  2729.  
  2730.                 case tokstop:
  2731.                     ctrl=1;
  2732.                     break;
  2733.  
  2734.                 case tokcont:
  2735.                     if(cont->flagcont)
  2736.                     {
  2737.                         disposetokens(&V.t);
  2738.                         V.t=cont->savetok;
  2739.                         stmtline=cont->saveline;
  2740.                         V.gotoflag=cont->savegoto;
  2741.                         V.elseflag=cont->saveelse;
  2742.                         cm=cont->cm;
  2743.                         rev_mode=cont->rev_mode;
  2744.                         cont->flagcont=false;
  2745.                     }
  2746.                     break;
  2747.  
  2748.                 case tokfor:
  2749.                     cmdfor(&V);
  2750.                     break;
  2751.  
  2752.                 case toknext:
  2753.                     cmdnext(&V);
  2754.                     break;
  2755.  
  2756.                 case tokwhile:
  2757.                     cmdwhile(&V);
  2758.                     break;
  2759.  
  2760.                 case tokwend:
  2761.                     cmdwend(&V);
  2762.                     break;
  2763.  
  2764.                 case tokgosub:
  2765.                     cmdgosub(&V);
  2766.                     break;
  2767.  
  2768.                 case tokreturn:
  2769.                     cmdreturn(&V);
  2770.                     break;
  2771.  
  2772.                 case tokread:
  2773.                     cmdread(&V);
  2774.                     break;
  2775.  
  2776.                 case tokdata:
  2777.                     cmddata(&V);
  2778.                     break;
  2779.  
  2780.                 case tokrestore:
  2781.                     cmdrestore(&V);
  2782.                     break;
  2783.  
  2784.                 case tokgotoxy:
  2785.                     cmdgotoxy(&V);
  2786.                     break;
  2787.  
  2788.                 case tokon:
  2789.                     cmdon(&V);
  2790.                     break;
  2791.  
  2792.                 case tokdim:
  2793.                     cmddim(&V);
  2794.                     break;
  2795.  
  2796.                 case tokpokel: bytes=4;goto poke;
  2797.                 case tokpokew: bytes=2;goto poke;
  2798.                 case tokpoke:  bytes=1;
  2799. poke:               cmdpoke(&V);
  2800.                     break;
  2801.  
  2802.                 case tokdegree:
  2803.                 case tokgrad:
  2804.                 case tokrad:
  2805.                     unit=stmttok->kind;
  2806.                     break;
  2807.  
  2808.                 case tokcls:
  2809.                     Printf("\033E");
  2810.                     break;
  2811.  
  2812.                 case tokfopen:
  2813.                     stringexpr(filename,&V);
  2814.                     binary=false;
  2815.                     if(!iseos(&V))
  2816.                     {
  2817.                         require(tokcomma,&V);
  2818.                         p=s=strexpr(&V);
  2819.                         while(*p)
  2820.                         {
  2821.                             switch(*p++)
  2822.                             {
  2823.                                 int Fdelete(const char *);
  2824.                                 case 'b':
  2825.                                 case 'B':
  2826.                                     binary=true;
  2827.                                     break;
  2828.                                 case 'n':
  2829.                                 case 'N':
  2830.                                     Fdelete(filename);
  2831.                                     break;
  2832.                                 default:
  2833.                                     errormsg("bad option for FOPEN");
  2834.                             }
  2835.                         }
  2836.                         Free(s);
  2837.                     }
  2838.                     fileposition=0;
  2839.                     break;
  2840.  
  2841.                 case tokfclose:
  2842.                     DATAfclose(1);
  2843.                     *filename=0;
  2844.                     break;
  2845.  
  2846.                 case tokclear:
  2847.                     clearall();
  2848.                     break;
  2849.  
  2850.                 case tokusing:
  2851.                     cmdusing(&V,0);
  2852.                     break;
  2853.  
  2854.                 case tokusing_:
  2855.                     cmdusing(&V,1);
  2856.                     break;
  2857.  
  2858.                 case tokplot:
  2859.                     cmdplot(&V);
  2860.                     break;
  2861.                 case tokline:
  2862.                     cmdline(&V);
  2863.                     break;
  2864.                 case tokcircle:
  2865.                     cmdcircle(&V);
  2866.                     break;
  2867.                 case tokoutbyte:
  2868.                     s=strexpr(&V);
  2869.                     cmdoutbyte(&V,s);
  2870.                     Free(s);
  2871.                     break;
  2872.                 default:
  2873.                     errormsg("Illegal command");
  2874.                     break;
  2875.                 }
  2876.             }
  2877.  
  2878.             if (!V.elseflag && !iseos(&V)) checkextra(&V);
  2879.             stmttok = V.t;
  2880.  
  2881.             BreakBASIC();       /* Und mal abbrechen ...    @@@ */
  2882.  
  2883.             if(ctrl) goto _Ltr1;
  2884.  
  2885.         } while ( V.t != NULL);
  2886.         
  2887.         if(stmtline != NULL)
  2888.         {
  2889.             if(tron)
  2890.             {
  2891.                 Printf("\nTRON %ld: ",stmtline->num);
  2892.                 listtokens(stdout,stmtline->txt);
  2893.                 Gets(STR1);
  2894.                 if(ctrl) goto _Ltr1;
  2895.             }
  2896.             if(!V.gotoflag) stmtline = stmtline->next;
  2897.             if(stmtline!=NULL) stmttok = stmtline->txt;
  2898.         }
  2899.  
  2900.     } while(stmtline != NULL);
  2901.  
  2902.     RECOVER2(try1,_Ltr1);
  2903.  
  2904.     if(ctrl)
  2905.     {
  2906.         Printf("\r\n\aBreak");
  2907.         disposetokens(&(cont->savetok));
  2908.         cont->savetok=stmttok;
  2909.         cont->saveline=stmtline;
  2910.         cont->savegoto=V.gotoflag;
  2911.         cont->saveelse=V.elseflag;
  2912.         cont->cm=cm;
  2913.         cont->rev_mode=rev_mode;
  2914.         cont->flagcont=true;
  2915.     }
  2916.     else if(P_escapecode != 42)
  2917.     {
  2918.         switch(P_escapecode)
  2919.         {
  2920.         case -2:
  2921.             Printf("Memory fault");
  2922.             break;
  2923.  
  2924.         case -10:
  2925.             ioerrmsg = (Char *)BASalloc(256);
  2926.             sprintf(ioerrmsg, "I/O Error %d", (int)P_ioresult);
  2927.             Printf("\007%s", ioerrmsg);
  2928.             Free(ioerrmsg);
  2929.             break;
  2930.  
  2931.         default:
  2932.             if(EXCP_LINE != -1)
  2933.                 Printf(" %ld\n", EXCP_LINE);
  2934.             _Escape(P_escapecode);
  2935.             break;
  2936.         }
  2937.     }
  2938.  
  2939.     if(stmtline != NULL) Printf(" in %ld", stmtline->num);
  2940.     Putchar('\n');
  2941.     ENDTRY(try1);
  2942. }   /*exec*/
  2943.  
  2944. int basic(int argc, Char *argv[])
  2945. {
  2946.     PASCAL_MAIN(argc, argv);
  2947.     linebase = NULL;
  2948.     varbase  = NULL;
  2949.     loopbase = NULL;
  2950.     exitflag = false;
  2951.     unit=tokrad;
  2952.     *filename=0;
  2953.     useprec=10;
  2954.     useprec_=255;
  2955.     usewidth=0;
  2956.     usewidth_=0;
  2957.     useleft=0;
  2958.     useleft_=0;
  2959.  
  2960.     Printf(
  2961.     "\033E\033p Chipmunk-BASIC \033q v1.00\n"
  2962.     "by David Gillespie\n\n"
  2963.     "\033p CPX-BASIC \033q vX.yz\n"
  2964.     "by Oliver Teuber, Jan Starzynski"
  2965.     "and Torsten Dix\n\n");
  2966.  
  2967.     do
  2968.     {
  2969.         TRY(try2);
  2970.         do
  2971.         {
  2972.             while(1)
  2973.             {
  2974.                 ctrl=0;
  2975.                 esc=0;
  2976.                 Printf("\033q\033e>");
  2977.                 Gets(inbuf);
  2978.                 if(ctrl==0) break;
  2979.                 Putchar('\n');
  2980.             }
  2981.             parseinput(&buf);
  2982.             if(curline == 0)
  2983.             {
  2984.                 stmtline = NULL;
  2985.                 stmttok = buf;
  2986.                 if(stmttok != NULL) exec();
  2987.                 if(!ctrl) disposetokens(&buf);
  2988.             }
  2989.         }
  2990.         while(!exitflag);
  2991.  
  2992.         RECOVER(try2);
  2993.         if(P_escapecode!=-20)
  2994.             Printf("Error %d/%d!\n", (int)P_escapecode, (int)P_ioresult);
  2995.         else
  2996.             Putchar('\n');
  2997.         ENDTRY(try2);
  2998.     }   while( !exitflag);
  2999.  
  3000.     return EXIT_SUCCESS;
  3001. }
  3002.